#include <stdlib.h>
#include <stdio.h>

#include "liste.h"

/*
	teste si un etat cible est présent dans une liste_s d'etat.
*/
int search_liste( const char etat_cible, liste_s *liste){
	//	on parcourt la liste, si on trouve la valeur recherche on retourne 1
	while( liste != NULL ){
		if( liste->state == etat_cible )
			return 1;
		liste = liste->suiv;
	}

	//	si on quitte la boucle c'est que la valeur recherche n'a pas ete trouve donc on retourne 0
	return 0;
}

/*
	Ajoute un entier dans une liste_s d'entier trié.
*/
void ajouteListe(liste_s** l,int q){
        liste_s* ptl;
        liste_s* tmp;
        ptl=*l;
        //	si la liste est vide on crée l'element au debut
        if(!ptl){
                ptl = (liste_s*) malloc(sizeof(liste_s));
		if (ptl == NULL){
		    fprintf(stderr, "Erreur lors d'allocation memoire\n");
		    exit(EXIT_FAILURE);
		}
		
                ptl->state=q;
                ptl->suiv=NULL;
                *l=ptl;
                return;
        }
        //	si l'element a placer est le premier element de la liste on ne fait rien (pas de doublon)
        if(ptl->state == q){
         return;
        }
        //	si l'element a placer est plus petit que le premier element de la liste, on place l'element en debut de liste
        if(q< ptl->state){
                tmp=*l;
                *l=(liste_s*) malloc(sizeof(liste_s));
		if (*l == NULL){
		    fprintf(stderr, "Erreur lors d'allocation memoire\n");
		    exit(EXIT_FAILURE);
		}
		
                (*l)->state=q;
                (*l)->suiv=tmp;
                return;
        }
        //	tant qu'on est pas au dernier element et que l'element suivant est plus petit que l'element a placer on parcourt la liste
        while(ptl->suiv && ptl->suiv->state <q){
                ptl=ptl->suiv;
        }
        //	si on est sortit de la boucle soit on est à la fin de la liste soit l'element suivant est plus grand que l'element a placer

        //	si on est sur le dernier element, on ajoute l'element à la suite
        if(!ptl->suiv){
                ptl->suiv=(liste_s*) malloc(sizeof(liste_s));
		if (ptl->suiv == NULL){
		    fprintf(stderr, "Erreur lors d'allocation memoire\n");
		    exit(EXIT_FAILURE);
		}
	
                ptl=ptl->suiv;
                ptl->state=q;
                ptl->suiv=NULL;
                return;
        }
        //	si l'element suivant est identique a l'element a placer on ne fait rien
        if(ptl->suiv->state==q){
                return;
        }

        //	sinon il faut intercaler l'element
        tmp=ptl->suiv;
        ptl->suiv=(liste_s*) malloc(sizeof(liste_s));
	if (ptl->suiv == NULL){
	  fprintf(stderr, "Erreur lors d'allocation memoire\n");
	  exit(EXIT_FAILURE);
	}
	
        ptl=ptl->suiv;
        ptl->state=q;
        ptl->suiv=tmp;
}

/*
 * Calcul la taille d'une liste_s d'etat cible.
 * On parcourt la liste, tant quelle ne vaut pas NULL on incremente la taille
 */
int listeLen( const liste_s *liste ){
	//	compte la taille de la liste
	int taille = 0;

	//	On parcourt toute la liste en incrementant de 1 la variable taille
	while( liste ){
		taille++;
		liste = liste->suiv;
	}

	return taille;
}

/*
 * Libere la mémoire utilisé par la liste_s passé en parametre.
 * On parcourt la liste_s et pour chaque element, on libere le suivant avant de liberer l'actuel.
 * Il s'agit donc d'une fonction recursive (pour eviter d'avoir a conserver l'adresse de l'element suivant avant de le supprimer)
 */
void libere_liste( liste_s **liste ){
	liste_s *memoire = NULL;

	while( *liste != NULL ){
		memoire = *liste;
		*liste = memoire->suiv;
		free( memoire );
	}
}

void supprime_element( const int element, liste_s **liste ){
	liste_s *prec = NULL;
	liste_s *courant = NULL;
	if( *liste == NULL )
		return;
	if( (*liste)->state == element ){
		prec = *liste;
		*liste = prec->suiv;
		free( prec );
	}else{
		prec = *liste;
		courant = (*liste)->suiv;
		while( courant != NULL ){
			if( courant->state == element ){
				prec->suiv == courant->suiv;
				free( courant );
				return;
			}
			prec = prec->suiv;
			courant = courant->suiv;
		}
	}
}

void print_liste( liste_s *liste ){
	while( liste != NULL ){
		printf("%d ", liste->state);
		liste = liste->suiv;
	}
	printf("\n");
}

int intInListe( liste_s *liste, const int valeur ){
	while( liste != NULL ){
		if( valeur == liste->state )
			return 1;
		liste = liste->suiv;
	}

	return 0;

}